iT邦幫忙

2021 iThome 鐵人賽

DAY 25
2
Modern Web

ASP.NET Web Forms 入門 - 30天建立遊艇網頁專案後端及後台功能 C#系列 第 25

Day 25 - 將 Yacht Manager 後台儲存資料提取後,送至前台渲染 Yachts 版面重覆區塊 - 前台 Master Page 製作 - ASP.NET Web Forms C#

  • 分享至 

  • xImage
  •  

=x= 🌵 Yachts 前台頁面 - Yachts - Master Page 後端功能製作。


Yachts 頁面資料分析介紹 :

📌 進到 Yachts 頁面後會發現,點擊遊艇型號側邊欄畫面會變動內容的包含 :

https://ithelp.ithome.com.tw/upload/images/20211009/20139487bbqi7SMgOb.jpg

  1. 紅色區塊 - 上方輪播圖依照各型號撥放。
  2. 紅色區塊 - 內容區塊的大小標題會變為該型號
  3. 紅色區塊 - 內部上方分頁會因型號有無影片而決定是否出現 Video 內容分頁鈕
  4. 綠色區塊 - 內容區塊首次進入時會出現第一個型號的 Overview 內容分頁,但切換內容分頁後再點擊不同型號,則會出現同內容分頁但不同型號的對應內容;特殊情況的 Video 頁面,則是如果在 Video 分頁選其它型號時,選到的型號有 Video 頁則會出現此型號的 Video 頁,假設選到的型號沒有 Video 內容,就會顯示這個型號的 Overview 內容分頁。

👺 從上面的拆分可以發現如果從綠色區塊來看,他在切換內容分頁時,不會變動的區塊就是紅色區塊,所以紅色區塊我們就可以製作成 Master Page,而綠色區塊則是 Content Page,但是因為區塊如果點擊遊艇型號側邊欄則會對應改變紅色跟綠色區塊,因此主版頁面的後置程式碼需要處理這些變動的對應。



Yachts - Master Page 主版頁面實作 :

1. 於前台檔案資料夾右鍵新增 Master Page 並將原 Yachts_OverView.html 的<head><body>內的內容分別複製到 .Master 檔案中。


2. 刪除與 VIEWSTATE 有關的程式碼。


3. 使用取代功能將 .html 都取代為 .aspx。


4. 遊艇型號輪播圖使用 Literal 控制項來送圖片內容,細節參考如下 :

a. 紫色底線 : 用來隱藏上方輪播相簿,若要使用可參考下一步驟說明。
b. 紅色區塊 : 輪播相簿接收區塊,使用 asp:Repeater 控制項 JavaScript 才能正確抓到。

https://ithelp.ithome.com.tw/upload/images/20211009/20139487pqRG8oLU1V.jpg


5. 將 <head> 內自動產生用來接收 <head> 內容資料的控制項移至 <head> 標籤內最下方

https://ithelp.ithome.com.tw/upload/images/20211009/201394870hEp8sQ9qX.jpg

  • 🌵 如果有要使用隱藏相簿功能,jQuery 類別名稱記得修正為框起的地方。


6. 左側邊欄遊艇型號選單使用 asp:Literal 控制項接收資料

https://ithelp.ithome.com.tw/upload/images/20211009/20139487JsSJPGso6J.jpg


7. 內容分頁選單用 asp:Literal 控制項接收資料,自動產生用來接收內容資料的控制項移至該處

https://ithelp.ithome.com.tw/upload/images/20211009/201394870ZrsVzHqgp.jpg


8. 在後置程式碼 .master.cs 的 Page_Init 加入取得側邊欄遊艇型號網址傳值 GUID 的方法

protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack) {
        //將型號對應 guid 存入 Session 與子頁共用
        getGuid(); //要放在 Init 不然 Content 頁會去先去抓 Session 而抓不到
    }
}
  • 👺 用除錯模式可以發現換頁時是先讀 Content 頁,再讀 Master 頁,所以才放在 Init。

  • 👺 執行順序 : Content 頁 Init > Master 頁 Init > Content 頁 Load > Master 頁 Load。


9. 建立取得遊艇型號對應 GUID 的 getGuid(); 方法邏輯如下

private void getGuid()
{
    //取得網址傳值的型號對應 GUID
    string guidStr = Request.QueryString["id"];
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT TOP 1 guid FROM Yachts";
    SqlCommand command = new SqlCommand(sql, connection);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    if (reader.Read()) {
        //如果無網址傳值就用第一筆遊艇型號的 GUID
        if (String.IsNullOrEmpty(guidStr)) {
            guidStr = reader["guid"].ToString().Trim();
        }
    }
    connection.Close();
    //將 GUID 存入 Session 供上方列表共用
    Session["guid"] = guidStr;
}
  • 🌵 直接點 Yachts 頁會無網址傳值,直接用第一筆型號資料。

  • 🌵 點側邊欄時會更新型號網址傳值 GUID。


10. 在 Page_Load 加入渲染主版畫面各區塊方法

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack) {
        loadGallery(); //讀取並渲染上方相簿輪播
        loadLeftMenu(); //讀取並渲染左側型號邊欄
        loadTopMenu(); //讀取並渲染型號內容上方標題及分頁列
    }
}


11. 建立渲染上方相簿輪播的 loadGallery(); 方法程式邏輯如下

private void loadGallery()
{
    //建立資料表存資料
    DataTable dataTable = new DataTable();
    //新增表格欄位,預設從 1 開始, 設定欄位名稱
    dataTable.Columns.AddRange(new DataColumn[1] { new DataColumn("ImageUrl") });

    //取得 Session 共用 GUID,Session 物件需轉回字串
    string guidStr = Session["guid"].ToString();
    //依 GUID 取得遊艇輪播圖片資料
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT bannerImgPathJSON FROM Yachts WHERE guid = @guidStr";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@guidStr", guidStr);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    List<ImagePath> savePathList = new List<ImagePath>();
    if (reader.Read()) {
        string loadJson = HttpUtility.HtmlDecode(reader["bannerImgPathJSON"].ToString());
        savePathList = JsonConvert.DeserializeObject<List<ImagePath>>(loadJson);
        foreach (var item in savePathList) {
            //逐一填入圖片路徑欄位值
            dataTable.Rows.Add($"upload/Images/{item.SavePath}");
        }
    }
    connection.Close();

    //輪播圖片必須用 Repeater 送不然 JavaScript 抓不到 HTML 標籤會失敗
    //設定用 Eval 綁定的輪播圖片路徑資料
    RepeaterImg.DataSource = dataTable; //設定資料來源
    RepeaterImg.DataBind(); //刷新圖片資料
}

//型號輪播圖片 JSON 資料
public class ImagePath
{
    public string SavePath { get; set; }
}


12. 建立渲染左側型號邊欄的 loadLeftMenu(); 方法程式邏輯如下

private void loadLeftMenu()
{
    string urlPathStr = System.IO.Path.GetFileName(Request.PhysicalPath);
    //取得遊艇型號資料
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT * FROM Yachts";
    SqlCommand command = new SqlCommand(sql, connection);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    StringBuilder leftMenuHtml = new StringBuilder();
    while (reader.Read()) {
        string yachtModelStr = reader["yachtModel"].ToString();
        string isNewDesignStr = reader["isNewDesign"].ToString();
        string isNewBuildingStr = reader["isNewBuilding"].ToString();
        string guidStr = reader["guid"].ToString();
        string isNewStr = "";
        //依是否為新建或新設計加入標註
        if (isNewDesignStr.Equals("True")) {
            isNewStr = "(New Design)";
        }
        else if (isNewBuildingStr.Equals("True")) {
            isNewStr = "(New Building)";
        }
        leftMenuHtml.Append($"<li><a href='{urlPathStr}?id={guidStr}'>{yachtModelStr} {isNewStr}</a></li>");
    }
    connection.Close();

    //渲染左側遊艇型號選單
    LeftMenuHtml.Text = leftMenuHtml.ToString();
}
  • 🌵 依型號標註判斷類型加入文字標示於型號後方。

  • 👺 連結位置要配合目前所在的內容分頁設定,於 Video 頁製作時,會建立如果跳轉到沒有影片連結的型號,會自動跳轉成型號的 Overview 內容分頁。


13. 建立渲染型號內容上方標題及分頁列的 loadTopMenu(); 方法程式邏輯如下

private void loadTopMenu()
{
    //取得 Session 共用 GUID,Session 物件需轉回字串
    string guidStr = Session["guid"].ToString();
    //依 GUID 取得遊艇資料
    List<RowData> saveRowList = new List<RowData>();
    SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["TayanaYachtConnectionString"].ConnectionString);
    string sql = "SELECT * FROM Yachts WHERE guid = @guidStr";
    SqlCommand command = new SqlCommand(sql, connection);
    command.Parameters.AddWithValue("@guidStr", guidStr);
    connection.Open();
    SqlDataReader reader = command.ExecuteReader();
    StringBuilder topMenuHtmlStr = new StringBuilder();
    StringBuilder dimensionsTableHtmlStr = new StringBuilder();
    if (reader.Read()) {
        string yachtModelStr = reader["yachtModel"].ToString();
        string contentHtmlStr = HttpUtility.HtmlDecode(reader["overviewContentHtml"].ToString());
        string loadJson = HttpUtility.HtmlDecode(reader["overviewDimensionsJSON"].ToString());
        string dimensionsImgPathStr = reader["overviewDimensionsImgPath"].ToString();
        string downloadsFilePathStr = reader["overviewDownloadsFilePath"].ToString();

        //加入渲染型號內容上方分類連結列表
        topMenuHtmlStr.Append($"<li><a class='menu_yli01' href='Yachts_OverView.aspx?id={guidStr}' >OverView</a></li>");
        topMenuHtmlStr.Append($"<li><a class='menu_yli02' href='Yachts_Layout.aspx?id={guidStr}' >Layout & deck plan</a></li>");
        topMenuHtmlStr.Append($"<li><a class='menu_yli03' href='Yachts_Specification.aspx?id={guidStr}' >Specification</a></li>");
        //加入渲染型號內容上方分類連結列表 Video 分頁標籤,有存影片連結網址才渲染
        saveRowList = JsonConvert.DeserializeObject<List<RowData>>(loadJson);
        if (!String.IsNullOrEmpty(saveRowList[0].SaveValue)) {
            topMenuHtmlStr.Append($"<li><a class='menu_yli04' href='Yachts_Video.aspx?id={guidStr}' >Video</a></li>");
        }

        //渲染畫面
        //渲染上方小連結
        LabLink.InnerText = yachtModelStr;
        //渲染標題
        LabTitle.InnerText = yachtModelStr;
        //渲染型號內容上方分類連結列表
        TopMenuLinkHtml.Text = topMenuHtmlStr.ToString();
    }
    connection.Close();
}

//表格欄位 JSON 資料
public class RowData
{
    public string SaveItem { get; set; }
    public string SaveValue { get; set; }
}
  • 🌵 Video 分頁標籤記得要特別處理是否顯示。


本日總結 :

📢 今天的內容可以複習如何設定主版頁面,之前是在後台使用,這次是前台頁面使用,這樣可以大量減少重複的程式碼內容,所有遊艇型號內容分頁共用相同邏輯的主版頁面,裡面側邊欄會依照目前所在內容分頁而改變連結網址,是根據原始網站的模式,也可以都導回到各個型號的 Overview 頁面會比較簡單,但使用者操作體驗較差,需要多做一次點選分頁內容,才能比對不同型號的相同內容。

  • 明日將介紹製作 OverView - Content Page 後端的相關細節。

上一篇
Day 24 - 依 Yachts 前台頁面分析拆解後,逐步建立 Overview 後台功能 - 動態新增欄位 - ASP.NET Web Forms C#
下一篇
Day 26 - 將 Yacht 後台儲存資料提取後,送至前台渲染 OverView 版面內容區塊 - 前台 Content Page 製作 - ASP.NET Web Forms C#
系列文
ASP.NET Web Forms 入門 - 30天建立遊艇網頁專案後端及後台功能 C#30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言